|
CallGraph
|
00001 #include "dotwriter.h" 00002 #include <wx/strconv.h> 00003 #include <wx/file.h> 00004 #include <wx/msgdlg.h> 00005 //#include <wx/math.h> 00006 00007 00008 DotWriter::DotWriter() 00009 { 00010 begin_graph = wxT("digraph\n{"); 00011 end_graph = wxT("}\n"); 00012 fontname = wxT("Arial"); 00013 style = wxT("filled"); 00014 shape = wxT("box"); 00015 cwhite = wxT("white"); 00016 cblack = wxT("black"); 00017 hnode = wxT(""); 00018 dedge = wxT(""); 00019 hedge = wxT(""); 00020 dlabel = wxT(""); 00021 graph = wxT(""); 00022 output = wxT(""); 00023 mlines = NULL; 00024 m_mgr = NULL; 00025 dwcn = 0; 00026 dwce = 0; 00027 dwtn = 0; 00028 dwte = 0; 00029 dwbname = false; 00030 dwbparam = false; 00031 writedotfile = false; 00032 } 00033 00034 DotWriter::~DotWriter() 00035 { 00036 00037 } 00038 00039 void DotWriter::setLineParser(LineParserList *pLines )//, int numOfLines) 00040 { 00041 mlines = pLines; 00042 } 00043 00044 void DotWriter::setDotWriterFromDialogSettings(IManager *mgr) 00045 { 00046 m_mgr = mgr; 00047 m_mgr->GetConfigTool()->ReadObject(wxT("CallGraph"), &confData); 00048 dwcn = confData.GetColorsNode(); 00049 dwce = confData.GetColorsEdge(); 00050 dwtn = confData.GetTresholdNode(); 00051 dwte = confData.GetTresholdEdge(); 00052 dwbname = confData.GetBoxName(); 00053 dwbparam = confData.GetBoxParam(); 00054 } 00055 00056 00057 void DotWriter::WriteToDotLanguade() 00058 { 00059 int pl_index = 0; 00060 float pl_time = 0; 00061 bool is_node = false; 00062 wxArrayInt index_pl_nodes; 00063 00064 if (mlines == NULL) 00065 return; 00066 00067 graph = wxT("graph [ranksep=\"0.25\", fontname=") + fontname + wxT(", nodesep=\"0.125\"];"); 00068 00069 hnode = wxT("node [label=\"\\N\", fontname=") + fontname + wxT(", style=") + style + wxT(", height=0, width=0, shape=") + shape + wxT(", fontcolor=") + cwhite + wxT("];"); 00070 00071 hedge = wxT("edge [fontname=") + fontname + wxT("];"); 00072 00073 //graph []; -- not used 00074 00075 output += begin_graph + wxT("\n") + graph + wxT("\n") + hnode + wxT("\n") + hedge + wxT("\n"); 00076 00077 LineParserList::compatibility_iterator it = mlines->GetFirst(); 00078 00079 while(it) 00080 { 00081 LineParser *line = it->GetData(); 00082 00083 //if (line->name.IsEmpty()) break; 00084 00085 if(line->pline && wxRound(line->time) >= dwtn) // rozliseni dle procentuelni vytizenosti primarniho uzlu ma vliv na vytvareni uzlu, predat info o pouzitych indexech 00086 { 00087 is_node = true; 00088 index_pl_nodes.Add(line->index); 00089 //wxMessageBox(wxString::Format(wxT("line->index primary: %i"),line->index)); 00090 dlabel = wxString::Format(wxT("%i"),line->index); 00091 dlabel += wxT(" [label=\""); 00092 dlabel += OptionsShortNameAndParameters(line->name); 00093 dlabel += wxT("\\n"); 00094 dlabel += wxString::Format(wxT("%.2f"), line->time); 00095 dlabel += wxT("% \\n"); 00096 dlabel += wxT("("); 00097 dlabel += wxString::Format(wxT("%.2f"), line->self); 00098 dlabel += wxT("%)"); 00099 dlabel += wxT("\\n"); 00100 if(line->called0 != -1) 00101 dlabel += wxString::Format(wxT("%i"),line->called0) + wxT("x"); 00102 dlabel += wxT("\",fontcolor=\""); 00103 dlabel += DefineColorForLabel(line->time); 00104 dlabel += wxT("\", color=\""); 00105 dlabel += DefineColorForNodeEdge(line->time, dwcn); 00106 // 00107 dlabel += wxT("\", fontsize=\"10.00\"];"); 00108 // 00109 output += dlabel + wxT("\n"); 00110 // 00111 dlabel.Clear(); 00112 } 00113 it = it->GetNext(); 00114 } 00115 00116 it = mlines->GetFirst(); 00117 00118 while(it) 00119 { 00120 LineParser *line = it->GetData(); 00121 00122 //if (line->name.IsEmpty()) break; 00123 00124 if(line->pline) 00125 { 00126 pl_index = line->index; // index for primary node 00127 pl_time = line->time; // time for primary node 00128 } 00129 00130 if (line->child && IsInArray(line->nameid,index_pl_nodes) && IsInArray(pl_index,index_pl_nodes) && (wxRound(pl_time) >= dwte)) 00131 { 00132 dedge = wxString::Format(wxT("%i"), pl_index); 00133 dedge += wxT(" -> "); 00134 dedge += wxString::Format(wxT("%i"),line->nameid); 00135 dedge += wxT(" [color=\""); 00136 dedge += DefineColorForNodeEdge(pl_time, dwce); // colorarow; // reseno dle vytizeni hlavniho uzlu 00137 dedge += wxT("\", label=\""); 00138 //if(line->self != -1) 00139 //dedge += wxString::Format(wxT("%.2f"),line->self) + wxT("%"); 00140 //dedge += wxT("\\n"); 00141 dedge += wxString::Format(wxT("%i"),line->called0); 00142 dedge += wxT("x"); 00143 dedge += wxT("\" ,arrowsize=\"0.50\", fontsize=\"10.00\", fontcolor=\""); 00144 dedge += cblack; 00145 dedge += wxT("\", labeldistance=\"4.00\", penwidth=\"2.00\"];"); 00146 // 00147 output += dedge + wxT("\n"); 00148 // 00149 dedge.Clear(); 00150 } 00151 it = it->GetNext(); 00152 } 00153 output += end_graph; 00154 if (!is_node) 00155 { 00156 output = wxT("digraph e {0 [label="); 00157 output += wxT("\"Call Graph is empty, please check settings of node resolutions for this plugin!\""); 00158 output += wxT(", shape=none, height=2, width=2, fontname=Arial, fontsize=14.00];}"); 00159 } 00160 } 00161 00162 void DotWriter::SendToDotAppOutputDirectory(wxString apppathfolder) 00163 { 00164 //wxMessageBox(apppathfolder); 00165 wxString dotfilespath = apppathfolder + stvariables::dotfilesdir + stvariables::sd; 00166 wxString dottxtpath = dotfilespath + stvariables::dottxtname; 00167 if(!wxDirExists(dotfilespath)) 00168 { 00169 wxMkdir(dotfilespath.c_str()); 00170 } 00171 00172 if (wxFileExists(dottxtpath)) 00173 wxRemoveFile(dottxtpath); 00174 00175 //create new txt file 00176 wxFile pFile(dottxtpath, wxFile::write); 00177 pFile.Open(dottxtpath, wxFile::write); 00178 00179 if(pFile.IsOpened()) 00180 { 00181 writedotfile = pFile.Write(output); 00182 pFile.Close(); 00183 } 00184 else 00185 { 00186 return; 00187 } 00188 } 00189 00190 bool DotWriter::DotFileExist(wxString apppathfolder) 00191 { 00192 wxString dotfilespath = apppathfolder + stvariables::dotfilesdir + stvariables::sd + stvariables::dottxtname; 00193 00194 if (wxFileExists(dotfilespath) && writedotfile) 00195 return true; 00196 else return false; 00197 } 00198 00199 wxString DotWriter::OptionsShortNameAndParameters(wxString name) 00200 { 00201 if (name.Contains(wxT('(')) && name.Contains(wxT(')')) && dwbname) 00202 { 00203 wxString out = name.BeforeFirst(wxT('(')); 00204 out += wxT("()"); // for function return just () 00205 return out; 00206 00207 } 00208 else if (name.Contains(wxT('(')) && name.Contains(wxT(')')) && dwbparam) 00209 { 00210 wxString out = name.BeforeFirst(wxT('(')); 00211 wxString sub = name.AfterFirst(wxT('(')).BeforeFirst(wxT(')')); 00212 if (sub.IsEmpty()) 00213 { 00214 out += wxT("\\n(\\n)"); 00215 return out; 00216 } 00217 else if(sub.Contains(wxT(","))) 00218 { 00219 sub.Replace(wxT(","), wxT(",\\n")); 00220 out += wxT("\\n(\\n") + sub + wxT("\\n)"); 00221 return out; 00222 } 00223 else 00224 { 00225 out += wxT("\\n(\\n") + sub + wxT("\\n)"); 00226 return out; 00227 00228 } 00229 } 00230 else return name; 00231 } 00232 00233 wxString DotWriter::DefineColorForNodeEdge(float time, int dwc) 00234 { 00235 wxString colors[11] = {wxT("#006837"), wxT("#1a9850"), wxT("#66bd63"), wxT("#a6d96a"), wxT("#d9ef8b"), wxT("#fee08b"), wxT("#fdae61"), wxT("#f46d43"), wxT("#d73027") ,wxT("#a50026"), wxT("a50026")}; 00236 int index = 0; 00237 int interval = 100 / (dwc-1); 00238 /* 00239 if (time == 100.00) 00240 { 00241 index = (time - 2) / interval; 00242 } 00243 else 00244 { 00245 index = time / interval; 00246 } 00247 00248 if (dwc > 1) 00249 { 00250 return colors[index]; 00251 } 00252 else return colors[0]; 00253 */ 00254 if(dwc == 1) 00255 { 00256 index = 0; 00257 } 00258 else if (time == 0.00) 00259 { 00260 index = 0; 00261 } 00262 else if (time == 100.00 && dwc == 2) 00263 { 00264 index = 1; 00265 } 00266 else 00267 { 00268 index = time / interval; 00269 wxMessageBox(wxString::Format(wxT("index: %i"),index)); 00270 } 00271 00272 return colors[index]; 00273 } 00274 00275 bool DotWriter::IsInArray(int index, wxArrayInt arr) 00276 { 00277 for(unsigned int i = 0; i < arr.GetCount(); i++) 00278 { 00279 if (arr.Item(i) == index) return true; 00280 } 00281 return false; 00282 00283 } 00284 00285 wxString DotWriter::DefineColorForLabel(float time) 00286 { 00287 int index = 0; 00288 int interval = 100 / dwcn; 00289 00290 if (time == 100.00) 00291 { 00292 index = (time - 2) / interval; 00293 } 00294 else 00295 { 00296 index = time / interval; 00297 } 00298 00299 if ((index < 3) || (index > 6)) 00300 { 00301 return cwhite; 00302 } 00303 else 00304 { 00305 return cblack; 00306 } 00307 }